package com.larly.controller;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.larly.annotation.AuthCheck;
import com.larly.common.BaseResponse;
import com.larly.common.DelectRequest;
import com.larly.common.IdRequest;
import com.larly.common.ResultUtils;
import com.larly.exception.ErrorCode;
import com.larly.exception.ThrowUtils;
import com.larly.model.domain.Notes;
import com.larly.model.domain.User;
import com.larly.model.dto.notes.AddNotesRequest;
import com.larly.model.dto.notes.EditNotesRequest;
import com.larly.model.dto.notes.RollbackNotesRequest;
import com.larly.model.dto.notes.SelectNotesRequest;
import com.larly.model.dto.noteshare.ShareNotesRequest;
import com.larly.model.vo.NoteVersionsVO;
import com.larly.model.vo.NotesVO;
import com.larly.model.vo.UserVO;
import com.larly.service.NoteSharesService;
import com.larly.service.NotesService;

import com.larly.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/notes")
@Slf4j
@Api(tags = "笔记模块")
public class NotesController {


    @Resource
    private NotesService notesService;

    @Resource
    private UserService userService;

    @Resource
    private NoteSharesService noteSharesService;

    /**
     * 添加笔记
     *
     * @param addNotesRequest
     * @return
     */
    @PostMapping("/add")
    @AuthCheck
    @ApiOperation("添加笔记")
    public BaseResponse<Long> addNote(@RequestBody AddNotesRequest addNotesRequest, HttpServletRequest request) {
        // 日志
        log.info("添加笔记：{}", addNotesRequest);
        long noteId = notesService.addNote(addNotesRequest, request);
        return ResultUtils.success(Long.valueOf(noteId));
    }

    /**
     * 修改笔记
     *
     * @param editNotesRequest
     * @return
     */
    @PostMapping("/edit")
    @AuthCheck
    @ApiOperation("修改笔记")
    public BaseResponse<Boolean> editNote(@RequestBody EditNotesRequest editNotesRequest, HttpServletRequest request) {
        // 日志
        log.info("修改笔记：{}", editNotesRequest);
        boolean result = notesService.editNote(editNotesRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 删除笔记
     */
    @PostMapping("/remove")
    @AuthCheck
    @ApiOperation("删除笔记")
    public BaseResponse<Boolean> removeNote(@RequestBody DelectRequest delectRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(delectRequest == null || delectRequest.getId() == null,
                ErrorCode.PARAM_ERROR, "笔记ID不能为空");
        Notes notes = notesService.getById(delectRequest.getId());
        ThrowUtils.throwIf(ObjUtil.isNull(notes), ErrorCode.PARAM_ERROR, "笔记不存在");
        User loginUser = userService.getLoginUser(request);
        ThrowUtils.throwIf(!loginUser.getId().equals(notes.getUserId()), ErrorCode.OPERATION_DENIED, "无权限删除该笔记");
        boolean result = notesService.removeById(notes);
        return ResultUtils.success(result);
    }


    /**
     * 将笔记放到回收站
     *
     * @param delectRequest
     * @return
     */
    @PostMapping("/delect")
    @AuthCheck
    @ApiOperation("将笔记放到回收站")
    public BaseResponse<Boolean> delectNote(@RequestBody DelectRequest delectRequest, HttpServletRequest request) {
        // 日志
        log.info("将笔记放到回收站：{}", delectRequest);
        boolean result = notesService.deleteNote(delectRequest, request);
        return ResultUtils.success(result);
    }


    /**
     * 清空回收站
     *
     * @return
     */
    @PostMapping("/clear")
    @AuthCheck
    @ApiOperation("清空回收站")
    public BaseResponse<Boolean> clearDeletedNotes(HttpServletRequest request) {
        // 日志
        log.info("清空回收站");
        boolean result = notesService.clearDeletedNotes(request);
        return ResultUtils.success(result);
    }

    /**
     * 恢复笔记
     */
    @PostMapping("/recovery")
    @AuthCheck
    @ApiOperation("恢复笔记")
    public BaseResponse<Boolean> recoveryNote(@RequestBody IdRequest idRequest, HttpServletRequest request) {
        // 日志
        log.info("恢复笔记：{}", idRequest);
        boolean result = notesService.recoverNote(idRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 回滚笔记
     *
     * @param rollbackNotesRequest
     * @return
     */
    @PostMapping("/rollback")
    @AuthCheck
    @ApiOperation("回滚笔记")
    public BaseResponse<NotesVO> rollbackNote(@RequestBody RollbackNotesRequest rollbackNotesRequest, HttpServletRequest request) {
        // 日志
        log.info("回滚笔记：{}", rollbackNotesRequest);
        NotesVO notesVo = notesService.rollbackNote(rollbackNotesRequest, request);
        return ResultUtils.success(notesVo);
    }


    /**
     * 获取笔记列表
     *
     * @param selectNotesRequest
     * @return
     */
    @PostMapping("/list/page")
    @ApiOperation("获取笔记列表")
    public BaseResponse<Page<NotesVO>> selectNotes(@RequestBody SelectNotesRequest selectNotesRequest) {
        Page<NotesVO> notesVoPage = notesService.selectNotes(selectNotesRequest);
        return ResultUtils.success(notesVoPage);
    }


    /**
     * 获取笔记详情
     *
     * @param noteId
     * @return
     */
    @GetMapping("/id")
    @ApiOperation("获取笔记详情")
    public BaseResponse<NotesVO> getNoteById(Integer noteId) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(noteId), ErrorCode.PARAM_ERROR, "笔记ID不能为空");
        Notes notes = notesService.getById(noteId);
        ThrowUtils.throwIf(ObjUtil.isNull(notes), ErrorCode.PARAM_ERROR, "笔记不存在");
        // 获取userId
        Integer userId = notes.getUserId();
        ThrowUtils.throwIf(ObjUtil.isNull(userId), ErrorCode.PARAM_ERROR, "用户ID不能为空");
        User user = userService.getById(userId);
        // 更新查看数+1
        boolean update = notesService.update(new UpdateWrapper<Notes>().eq("id", noteId).set("views", notes.getViews() + 1));
        ThrowUtils .throwIf(!update, ErrorCode.FAIL, "更新查看数失败");
        ThrowUtils.throwIf(ObjUtil.isNull(notes), ErrorCode.PARAM_ERROR, "笔记不存在");
        NotesVO notesVo = NotesVO.toVO(notes);
        notesVo.setUserVO(UserVO.toVO(user));
        return ResultUtils.success(notesVo);
    }

    /**
     * 获取版本记录指定的笔记
     */
    @PostMapping("/getNoteVersions")
    @AuthCheck
    @ApiOperation("获取版本记录指定的笔记")
    public BaseResponse<List<NoteVersionsVO>> getNoteVersions(@RequestBody IdRequest idRequest) {
        List<NoteVersionsVO> noteVersions = notesService.getNoteVersions(idRequest.getId());
        return ResultUtils.success(noteVersions);
    }

    /**
     * 点赞
     */
    @PostMapping("/likeNote")
    @AuthCheck
    @ApiOperation("点赞")
    public BaseResponse<Boolean> likeNote(@RequestBody IdRequest idRequest, HttpServletRequest request) {
        boolean result = notesService.likeNote(idRequest.getId(), request);
        return ResultUtils.success(result);
    }

    /**
     * 取消点赞
     */
    @PostMapping("/cancelLikeNote")
    @AuthCheck
    @ApiOperation("取消点赞")
    public BaseResponse<Boolean> cancelLikeNote(@RequestBody IdRequest idRequest, HttpServletRequest request) {
        boolean result = notesService.cancelLikeNote(idRequest.getId(), request);
        return ResultUtils.success(result);
    }

    /**
     * 前端获取笔记分类
     *
     */
    @GetMapping("/getNoteCategory")
    @ApiOperation("前端获取笔记分类")
    public BaseResponse<List<String>> getNoteCategory() {
        // 写死分类，后续可扩展
//        日常生活 学习记录 教程 美食 旅行 相册
        String[] category = {"日常生活", "学习记录", "教程", "美食", "旅行", "相册"};
        return ResultUtils.success(Arrays.asList(category));
    }

    /**
     * 上传笔记封面
     */
    @PostMapping("/uploadCover")
    @AuthCheck
    @ApiOperation("上传笔记封面")
    public BaseResponse<String> uploadCover(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isEmpty(file), ErrorCode.PARAM_ERROR, "文件不能为空");
        String result = notesService.uploadCover(file, request);
        return ResultUtils.success(result);
    }


    /**
     * 分享笔记
     */
    @PostMapping("/share")
    @AuthCheck
    @ApiOperation("分享笔记")
    public BaseResponse<String> shareNote(@RequestBody ShareNotesRequest shareNotesRequest, HttpServletRequest request) {
        log.info("分享笔记：{}", shareNotesRequest);
        String shareLink = noteSharesService.shareNote(shareNotesRequest, request);
        return ResultUtils.success(shareLink);
    }

    /**
     * 通过分享链接获取笔记
     */
    @GetMapping("/shared/{shareLink}")
    @ApiOperation("通过分享链接获取笔记")
    public BaseResponse<NotesVO> getNoteByShareLink(@PathVariable("shareLink") String shareLink) {
        NotesVO notesVo = noteSharesService.getNoteByShareLink(shareLink);
        return ResultUtils.success(notesVo);
    }
}
